package com.example.dialogfragmentlibrary.library2;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.example.dialogfragmentlibrary.R;
import com.example.dialogfragmentlibrary.library.Utils;
import com.example.dialogfragmentlibrary.library.ViewHolder;

/**
 * Builder layoutId====================================================
 * Build new====================================================
 * 构造 build====================================================
 * show====================================================
 * onAttach====================================================
 * onCreate====================================================
 * onCreateView====================================================
 * onStart====================================================
 * //旋转
 * onSaveInstanceState====================================================
 * 构造 空====================================================
 * onAttach====================================================
 * onCreate====================================================
 * onCreate savedInstanceState====================================================
 * onCreateView====================================================
 * onStart====================================================
 * //旋转
 * onSaveInstanceState====================================================
 * 构造 空====================================================
 * onAttach====================================================
 * onCreate====================================================
 * onCreate savedInstanceState====================================================
 * onCreateView====================================================
 * onStart====================================================
 */
public class CustomDialogFragment extends DialogFragment {

    private static final String MARGIN = "mMargin";
    private static final String WIDTH = "mWidth";
    private static final String HEIGHT = "mHeight";
    private static final String DIM = "dim_amount";
    private static final String GRAVITY = "mGravity";
    private static final String CANCEL = "out_cancel";
    private static final String THEME = "theme";
    private static final String ANIM = "anim_style";
    private static final String LAYOUT = "layout_id";
    private static final String LISTENER = "listener";

    private int mMargin;//左右边距
    private int mWidth;//宽度
    private int mHeight;//高度
    private float mDimAmount = 0.5f;//灰度深浅
    private int mGravity = Gravity.CENTER;//显示的位置
    private boolean mOutCancel = true;//是否点击外部取消
    @StyleRes
    protected int mTheme = R.style.NiceDialogFragmentStyle; // dialog主题
    @StyleRes
    private int mAnimStyle;
    @LayoutRes
    protected int mLayoutId;
    private Context mContext;
    private View mItemView;
    private OnConvertViewListener mListener;
    private static final String TAG = CustomDialogFragment.class.getSimpleName();

    /**
     * 空构造方法，避免报错
     */
    public CustomDialogFragment() {
        Log.e(TAG, "构造 空====================================================");
    }

    public CustomDialogFragment(Builder builder) {
        mMargin = builder.margin;
        mWidth = builder.width;
        mHeight = builder.height;
        mDimAmount = builder.dimAmount;
        mGravity = builder.gravity;
        mOutCancel = builder.outCancel;
        mTheme = builder.theme;
        mAnimStyle = builder.animStyle;
        mLayoutId = builder.layoutId;
        mContext = builder.mContext;
        mItemView = builder.mItemView;
        mListener = builder.mListener;
        Log.e(TAG, "构造 build====================================================");
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        this.mContext = context;
        Log.e(TAG, "onAttach====================================================");
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, mTheme);
        //恢复保存的数据
        Log.e(TAG, "onCreate====================================================");
        if (savedInstanceState != null) {
            Log.e(TAG, "onCreate savedInstanceState====================================================");
            mMargin = savedInstanceState.getInt(MARGIN);
            mWidth = savedInstanceState.getInt(WIDTH);
            mHeight = savedInstanceState.getInt(HEIGHT);
            mDimAmount = savedInstanceState.getFloat(DIM);
            mGravity = savedInstanceState.getInt(GRAVITY);
            mOutCancel = savedInstanceState.getBoolean(CANCEL);
            mTheme = savedInstanceState.getInt(THEME);
            mAnimStyle = savedInstanceState.getInt(ANIM);
            mLayoutId = savedInstanceState.getInt(LAYOUT);
            mListener = savedInstanceState.getParcelable(LISTENER);
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mItemView = inflater.inflate(mLayoutId, container, false);
        if (mListener != null) {
            mListener.onConvertView(ViewHolder.create(mItemView), this);
        }
        Log.e(TAG, "onCreateView====================================================");

        return mItemView;
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.e(TAG, "onStart====================================================");
        initParams();
    }

    /**
     * 屏幕旋转等导致DialogFragment销毁后重建时保存数据
     *
     * @param outState
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(MARGIN, mMargin);
        outState.putInt(WIDTH, mWidth);
        outState.putInt(HEIGHT, mHeight);
        outState.putFloat(DIM, mDimAmount);
        outState.putInt(GRAVITY, mGravity);
        outState.putBoolean(CANCEL, mOutCancel);
        outState.putInt(THEME, mTheme);
        outState.putInt(ANIM, mAnimStyle);
        outState.putInt(LAYOUT, mLayoutId);
        outState.putParcelable(LISTENER, mListener);
        Log.e(TAG, "onSaveInstanceState====================================================");

    }


    private void initParams() {
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        Window window = dialog.getWindow();
        if (window != null) {
            WindowManager.LayoutParams lp = window.getAttributes();
            //调节灰色背景透明度[0-1]，默认0.5f
            lp.dimAmount = mDimAmount;
            if (mGravity != 0) {
                lp.gravity = mGravity;
            }
            switch (mGravity) {
                case Gravity.START:
                case (Gravity.START | Gravity.BOTTOM):
                case (Gravity.START | Gravity.TOP):
                    if (mAnimStyle == 0) {
                        mAnimStyle = R.style.LeftAnimation;
                    }
                    break;
                case Gravity.TOP:
                    if (mAnimStyle == 0) {
                        mAnimStyle = R.style.TopAnimation;
                    }
                    break;
                case Gravity.END:
                case (Gravity.END | Gravity.BOTTOM):
                case (Gravity.END | Gravity.TOP):
                    if (mAnimStyle == 0) {
                        mAnimStyle = R.style.RightAnimation;
                    }
                    break;
                case Gravity.BOTTOM:
                    if (mAnimStyle == 0) {
                        mAnimStyle = R.style.BottomAnimation;
                    }
                    break;
                default:
                    break;

            }

            //设置dialog宽度
            if (mWidth == 0) {
                lp.width = Utils.getScreenWidth(mContext) - 2 * Utils.dp2px(mContext, mMargin);
            } else if (mWidth == -1) {
                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
            } else {
                lp.width = Utils.dp2px(mContext, mWidth);
            }

            //设置dialog高度
            if (mHeight == 0) {
                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
            } else {
                lp.height = Utils.dp2px(mContext, mHeight);
            }

            //设置dialog进入、退出的动画
            window.setWindowAnimations(mAnimStyle);
            window.setAttributes(lp);
        }
        setCancelable(mOutCancel);
    }

    public static final class Builder {
        private int margin;
        private int width;
        private int height;
        private float dimAmount = 0.5f;
        private int gravity = Gravity.CENTER;
        private boolean outCancel = true;
        private int theme = R.style.NiceDialogFragmentStyle;
        private int animStyle;
        private int layoutId;
        private Context mContext;
        private View mItemView;
        private OnConvertViewListener mListener;

        public Builder() {
        }

        public Builder margin(int val) {
            margin = val;
            return this;
        }

        public Builder width(int val) {
            width = val;
            return this;
        }

        public Builder height(int val) {
            height = val;
            return this;
        }

        public Builder dimAmount(float val) {
            dimAmount = val;
            return this;
        }

        public Builder gravity(int val) {
            gravity = val;
            return this;
        }

        public Builder outCancel(boolean val) {
            outCancel = val;
            return this;
        }

        public Builder theme(int val) {
            theme = val;
            return this;
        }

        public Builder animStyle(int val) {
            animStyle = val;
            return this;
        }

        public Builder layoutId(int val) {
            layoutId = val;
            Log.e(TAG, "Builder layoutId====================================================");

            return this;
        }

        public Builder mContext(Context val) {
            mContext = val;
            return this;
        }

        public Builder mItemView(View val) {
            mItemView = val;
            return this;
        }

        public CustomDialogFragment build() {
            Log.e(TAG, "Build new====================================================");

            return new CustomDialogFragment(this);
        }

        public Builder listener(OnConvertViewListener val) {
            mListener = val;
            return this;
        }

        public Builder mMargin(int val) {
            margin = val;
            return this;
        }

        public Builder mWidth(int val) {
            width = val;
            return this;
        }

        public Builder mHeight(int val) {
            height = val;
            return this;
        }

        public Builder mDimAmount(float val) {
            dimAmount = val;
            return this;
        }

        public Builder mGravity(int val) {
            gravity = val;
            return this;
        }

        public Builder mOutCancel(boolean val) {
            outCancel = val;
            return this;
        }

        public Builder mTheme(int val) {
            theme = val;
            return this;
        }

        public Builder mAnimStyle(int val) {
            animStyle = val;
            return this;
        }

        public Builder mLayoutId(int val) {
            layoutId = val;
            return this;
        }
    }

    public CustomDialogFragment show(FragmentManager manager) {
        Log.e(TAG, "show====================================================");

        FragmentTransaction transaction = manager.beginTransaction();
        if (this.isAdded()) {
            transaction.remove(this).commit();
        }
        transaction.add(this, String.valueOf(System.currentTimeMillis()));
        transaction.commitAllowingStateLoss();
        return this;
    }
}
